using Microsoft.AspNetCore.Mvc;
using community.Models;
using System.ComponentModel.DataAnnotations;
using Microsoft.EntityFrameworkCore;
using community.Data;
using System.Security.Claims;

namespace community.Controllers
{
    /// <summary>
    /// 投诉建议查询参数
    /// </summary>
    public class ComplaintQueryDTO
    {
        /// <summary>
        /// 标题关键词
        /// </summary>
        public string? Title { get; set; }

        /// <summary>
        /// 处理状态（Pending-待处理/InProgress-处理中/Resolved-已解决）
        /// </summary>
        public string? Status { get; set; }

        /// <summary>
        /// 提交开始时间
        /// </summary>
        public DateTime? SubmitTimeStart { get; set; }

        /// <summary>
        /// 提交结束时间
        /// </summary>
        public DateTime? SubmitTimeEnd { get; set; }

        /// <summary>
        /// 提交用户ID（管理员可查询所有，普通用户只能查询自己的）
        /// </summary>
        public int? UserId { get; set; }

        /// <summary>
        /// 每页显示数量，默认10条
        /// </summary>
        [Range(1, 100)]
        public int PageSize { get; set; } = 10;

        /// <summary>
        /// 当前页码，默认第1页
        /// </summary>
        [Range(1, int.MaxValue)]
        public int PageNumber { get; set; } = 1;
    }

    /// <summary>
    /// 创建投诉建议的数据模型
    /// </summary>
    public class ComplaintCreateDTO
    {
        /// <summary>
        /// 投诉标题
        /// </summary>
        [Required(ErrorMessage = "标题不能为空")]
        [StringLength(200, ErrorMessage = "标题最多200个字符")]
        public string Title { get; set; }

        /// <summary>
        /// 投诉详细描述
        /// </summary>
        [Required(ErrorMessage = "描述不能为空")]
        [StringLength(2000, ErrorMessage = "描述最多2000个字符")]
        public string Description { get; set; }
    }

    /// <summary>
    /// 处理投诉建议的数据模型
    /// </summary>
    public class ComplaintProcessDTO
    {
        /// <summary>
        /// 处理状态
        /// </summary>
        [Required(ErrorMessage = "处理状态不能为空")]
        [RegularExpression("^(Processed|Pending)$", ErrorMessage = "状态必须是 InProgress 或 Resolved")]
        public string Status { get; set; }

        /// <summary>
        /// 处理响应/反馈内容
        /// </summary>
        [Required(ErrorMessage = "处理响应不能为空")]
        [StringLength(1000, ErrorMessage = "处理响应最多1000个字符")]
        public string Response { get; set; }
    }

    /// <summary>
    /// 投诉建议管理接口
    /// </summary>
    [ApiController]
    [Route("api/[controller]")]
    public class ComplaintController : ControllerBase
    {
        private readonly ApplicationDbContext _context;

        public ComplaintController(ApplicationDbContext context)
        {
            _context = context;
        }

        /// <summary>
        /// 获取投诉建议列表（支持分页和条件筛选）
        /// </summary>
        /// <param name="query">查询参数</param>
        /// <returns>投诉建议列表和总数</returns>
        /// <response code="200">成功获取投诉建议列表</response>
        /// <response code="400">查询参数验证失败</response>
        [HttpGet]
        [ProducesResponseType(StatusCodes.Status200OK)]
        [ProducesResponseType(StatusCodes.Status400BadRequest)]
        public async Task<IActionResult> GetComplaints([FromQuery] ComplaintQueryDTO query)
        {
            var complaints = _context.Complaints.AsQueryable();

            if (!string.IsNullOrEmpty(query.Title))
                complaints = complaints.Where(c => c.Title.Contains(query.Title));

            if (!string.IsNullOrEmpty(query.Status))
                complaints = complaints.Where(c => c.Status == query.Status);

            if (query.SubmitTimeStart.HasValue)
                complaints = complaints.Where(c => c.SubmittedAt >= query.SubmitTimeStart);

            if (query.SubmitTimeEnd.HasValue)
                complaints = complaints.Where(c => c.SubmittedAt <= query.SubmitTimeEnd);

            // 获取当前用户信息
            var currentUserId = GetCurrentUserId();
            var isAdmin = IsCurrentUserAdmin();

            // 如果不是管理员，只能查看自己的投诉
            if (!isAdmin)
            {
                complaints = complaints.Where(c => c.UserId == currentUserId);
            }

            var total = await complaints.CountAsync();
            var pagedComplaints = await complaints
                .OrderByDescending(c => c.SubmittedAt)
                .Skip((query.PageNumber - 1) * query.PageSize)
                .Take(query.PageSize)
                .Select(c => new
                {
                    c.Id,
                    c.Title,
                    c.Description,
                    c.Status,
                    c.SubmittedAt,
                    c.ProcessedAt,
                    c.Response,
                    User = _context.Residents
                        .Where(u => u.Id == c.UserId) // 手动查询 User
                        .Select(u => new
                        {
                            u.Name,
                            u.Phone
                        })
                        .FirstOrDefault() // 如果查不到 User，返回 null
                })
                .ToListAsync();

            

            return Ok(new
            {
                Total = total,
                Items = pagedComplaints
            });
        }

        /// <summary>
        /// 获取指定投诉建议的详细信息
        /// </summary>
        /// <param name="id">投诉建议ID</param>
        /// <returns>投诉建议详细信息</returns>
        /// <response code="200">成功获取投诉建议信息</response>
        /// <response code="404">指定ID的投诉建议不存在</response>
        [HttpGet("{id}")]
        [ProducesResponseType(StatusCodes.Status200OK)]
        [ProducesResponseType(StatusCodes.Status404NotFound)]
        public async Task<IActionResult> GetComplaint(int id)
        {
            var complaint = await _context.Complaints
                .Include(c => c.User)
                .FirstOrDefaultAsync(c => c.Id == id);
                
            if (complaint == null)
                return NotFound();

            // 权限检查
            var currentUserId = GetCurrentUserId();
            var isAdmin = IsCurrentUserAdmin();
            if (!isAdmin && complaint.UserId != currentUserId)
                return Forbid();

            return Ok(new
            {
                complaint.Id,
                complaint.Title,
                complaint.Description,
                complaint.Status,
                complaint.SubmittedAt,
                complaint.ProcessedAt,
                complaint.Response,
                User = new
                {
                    complaint.User.Username,
                    complaint.User.Email
                }
            });
        }

        /// <summary>
        /// 提交新的投诉建议
        /// </summary>
        /// <param name="dto">投诉建议信息</param>
        /// <returns>新创建的投诉建议信息</returns>
        /// <response code="201">成功创建投诉建议</response>
        /// <response code="400">提供的数据无效</response>
        [HttpPost]
        [ProducesResponseType(StatusCodes.Status201Created)]
        [ProducesResponseType(StatusCodes.Status400BadRequest)]
        public async Task<IActionResult> CreateComplaint(ComplaintCreateDTO dto)
        {
            var currentUserId = GetCurrentUserId();

            var complaint = new Complaint
            {
                UserId = currentUserId,
                Title = dto.Title,
                Description = dto.Description,
                Status = "Pending",
                SubmittedAt = DateTime.UtcNow
            };

            _context.Complaints.Add(complaint);
            await _context.SaveChangesAsync();

            return CreatedAtAction(nameof(GetComplaint), new { id = complaint.Id }, complaint);
        }

        /// <summary>
        /// 处理投诉建议
        /// </summary>
        /// <param name="id">投诉建议ID</param>
        /// <param name="dto">处理信息</param>
        /// <returns>更新后的投诉建议信息</returns>
        /// <response code="200">成功处理投诉建议</response>
        /// <response code="400">提供的数据无效</response>
        /// <response code="404">指定ID的投诉建议不存在</response>
        [HttpPut("{id}/process")]
        [ProducesResponseType(StatusCodes.Status200OK)]
        [ProducesResponseType(StatusCodes.Status400BadRequest)]
        [ProducesResponseType(StatusCodes.Status404NotFound)]
        public async Task<IActionResult> ProcessComplaint(int id, ComplaintProcessDTO dto)
        {
            // 检查用户是否为管理员
            if (!IsCurrentUserAdmin())
                return Forbid();

            var complaint = await _context.Complaints.FindAsync(id);
            if (complaint == null)
                return NotFound();

            if (complaint.Status == "Processed")
                return BadRequest("该投诉建议已经处理完成");

            complaint.Status = dto.Status;
            complaint.Response = dto.Response;
            complaint.ProcessedAt = DateTime.UtcNow;

            await _context.SaveChangesAsync();
            return Ok(complaint);
        }

        /// <summary>
        /// 获取投诉建议统计信息
        /// </summary>
        /// <returns>统计信息</returns>
        /// <response code="200">成功获取统计信息</response>
        [HttpGet("statistics")]
        [ProducesResponseType(StatusCodes.Status200OK)]
        public async Task<IActionResult> GetStatistics()
        {
            var statistics = await _context.Complaints
                .GroupBy(c => c.Status)
                .Select(g => new
                {
                    Status = g.Key,
                    Count = g.Count()
                })
                .ToListAsync();

            var totalCount = statistics.Sum(s => s.Count);
            var pendingCount = statistics.FirstOrDefault(s => s.Status == "Pending")?.Count ?? 0;
            var inProgressCount = statistics.FirstOrDefault(s => s.Status == "InProgress")?.Count ?? 0;
            var resolvedCount = statistics.FirstOrDefault(s => s.Status == "Resolved")?.Count ?? 0;

            return Ok(new
            {
                Total = totalCount,
                Pending = pendingCount,
                InProgress = inProgressCount,
                Resolved = resolvedCount,
                ProcessingRate = totalCount > 0 
                    ? (double)(inProgressCount + resolvedCount) / totalCount 
                    : 0
            });
        }

        // 获取当前用户ID
        private int GetCurrentUserId()
        {
            var userIdClaim = User.FindFirst(ClaimTypes.NameIdentifier);
            if (userIdClaim == null || !int.TryParse(userIdClaim.Value, out int userId))
            {
                throw new UnauthorizedAccessException("无法获取当前用户ID");
            }
            return userId;
        }

        // 判断当前用户是否是管理员
        private bool IsCurrentUserAdmin()
        {
            var roleClaim = User.FindFirst(ClaimTypes.Role);
            return roleClaim?.Value == "Admin";
        }
    }
} 